package com.jjc.android.activity

import android.content.Context
import android.content.Intent
import android.graphics.BlurMaskFilter
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.github.mpcharting.charts.BubbleChart
import com.github.mpcharting.components.XAxis
import com.github.mpcharting.components.YAxis.AxisDependency
import com.github.mpcharting.data.BubbleData
import com.github.mpcharting.data.BubbleDataSet
import com.github.mpcharting.data.BubbleEntry
import com.github.mpcharting.interfaces.datasets.IBubbleDataSet
import com.hjq.toast.ToastUtils
import com.jjc.android.Constants
import com.jjc.android.R
import com.jjc.android.UserManager
import com.jjc.android.base.BaseActivity
import com.jjc.android.dialog.MessageImageDialog
import com.jjc.android.entity.*
import com.jjc.android.net.SimpleHttpCallback
import com.jjc.android.util.Common
import com.jjc.android.util.Common.formatHtml
import com.jjc.android.util.Common.parseEmpty
import com.jjc.android.util.ComplexSpannableStringUtils
import com.jjc.android.util.dp2px
import com.jjc.android.util.paramEx
import com.jjc.android.view.*
import com.lzy.okgo.OkGo
import com.zzhoujay.richtext.RichText
import java.util.Calendar

class DetectionReportActivity : BaseActivity(){

    companion object{
        fun start(context: Context,id:String){
            val intent = Intent(context,DetectionReportActivity::class.java)
            intent.putExtra(Constants.BUNDLE_ID,id)
            context.startActivity(intent)
        }
    }

    override val layoutId: Int = R.layout.activity_detection_report
    private val valueTxt1: TextView by lazy { findViewById<TextView>(R.id.valueTxt1) }
    private val nextTimeTxt: TextView by lazy { findViewById<TextView>(R.id.nextTimeTxt) }
    private val scatterChart: BubbleChart by lazy { findViewById<BubbleChart>(R.id.scatterChart) }
    private val timeTxt: TextView by lazy { findViewById<TextView>(R.id.timeTxt) }
    private val ageTxt: TextView by lazy { findViewById<TextView>(R.id.ageTxt) }
    private val productName2Txt: TextView by lazy { findViewById<TextView>(R.id.productName2Txt) }
    private val checkerNameTxt: TextView by lazy { findViewById<TextView>(R.id.checkerNameTxt) }
    private val resultUnit2Txt: TextView by lazy { findViewById<TextView>(R.id.resultUnit2Txt) }
    private val resultValue2Txt: TextView by lazy { findViewById<TextView>(R.id.resultValue2Txt) }
    private val resultUnitTxt: TextView by lazy { findViewById<TextView>(R.id.resultUnitTxt) }
    private val resultValueTxt: TextView by lazy { findViewById<TextView>(R.id.resultValueTxt) }
    private val productNameTxt: TextView by lazy { findViewById<TextView>(R.id.productNameTxt) }
    private val titleView: TextView by lazy { findViewById<TextView>(R.id.titleView) }
    private val shareBtn: ImageView by lazy { findViewById<ImageView>(R.id.shareBtn) }
    private val downloadBtn: ImageView by lazy { findViewById<ImageView>(R.id.downloadBtn) }
    private val chartUnitText:TextView by lazy { findViewById(R.id.chartUnitText) }
    private val reportErrorTxt:TextView by lazy { findViewById(R.id.reportErrorTxt) }
    private val contentLayout:View by lazy { findViewById(R.id.contentLayout) }
    private val sampleTxt:TextView by lazy { findViewById(R.id.sampleTxt) }
    private lateinit var detectionId:String
    private val shareView by lazy {
        layoutInflater.inflate(R.layout.view_detection_report_share,null)
    }
    override fun initView(savedInstanceState: Bundle?) {
        downloadBtn.visibility = View.GONE
        downloadBtn.onClick {
            CommonKt.downloadFile(this,"https://www.gjtool.cn/pdfh5/git.pdf",true,{
                ToastUtils.show("${getString(R.string.down_fail_txt)}:$it")
            }){
                ToastUtils.show("${getString(R.string.down_success_txt)}:${it.absolutePath}")
            }
        }
        shareBtn.onClick {
            if(mDetectionReportInfo==null)return@onClick
            MessageImageDialog.Builder(this@DetectionReportActivity)
                .imageResId(R.mipmap.alert_weishouquan_pic)
                .content(getString(R.string.share_report_hint_txt))
                .okClick {
                    val bitmap = CommonKt.convertViewToBitmap(shareView)
                    val uri: Uri = Uri.parse(
                        MediaStore.Images.Media.insertImage(
                            this.contentResolver,
                            bitmap,
                            null,
                            null
                        )
                    )
                    var intent = Intent()
                    intent.action = Intent.ACTION_SEND //设置分享行为
                    intent.type = "image/*" //设置分享内容的类型
                    intent.putExtra(Intent.EXTRA_STREAM, uri)
                    intent = Intent.createChooser(intent, getString(R.string.share_txt))
                    startActivity(intent)
                }
                .build()
                .show()
        }
        initChart(scatterChart,false)
        shareView.findViewById<BubbleChart>(R.id.scatterChart).let {
            initChart(it,true)
        }
        resultValueTxt.setOnLongClickListener {
            showTcRatio = !showTcRatio
            if(showTcRatio){
                resultUnitTxt.visibility = View.GONE
                resultValueTxt.text = mDetectionReportInfo?.tcRatio.parseEmpty()
            }else{
                resultUnitTxt.visibility = View.VISIBLE
                resultValueTxt.text = mDetectionReportInfo?.adjustedDisplayResult.parseEmpty()
            }
            true
        }
        showLoadingView(contentLayout)
        fetchPageInfo()
    }

    private var showTcRatio = false

    override fun fetchPageInfo() {
        OkGo.post<LzyResponse<DetectionReportInfo>>(Constants.getOneHealthRecordDetails)
            .paramEx(mutableMapOf(
                "tuoTuToken" to UserManager.userInfo().tuoTuToken,
                "detectionId" to detectionId
            ))
            .tag(this)
            .execute(object : SimpleHttpCallback<LzyResponse<DetectionReportInfo>>(false){
                override fun onCallSuccess(response: LzyResponse<DetectionReportInfo>) {
                    response.data.let {
                        if(it==null){
                            showEmptyView()
                        }else{
                            hideLoadingView()
                            loadPageInfo(it)
                        }
                    }
                }

                override fun onCallError(error: String?) {
                    showErrorView(error)
                }

            })
    }
    private var mDetectionReportInfo:DetectionReportInfo? = null
    private fun loadPageInfo(info:DetectionReportInfo){
        mDetectionReportInfo = info
        showTcRatio = false
        detailMarkerView.reportInfo = info
        titleView.text = String.format("%s${getString(R.string.dete_report)}",info.minorTermName.parseEmpty())
        productNameTxt.text = String.format("%s (%s)",info.minorTermName.parseEmpty(),info.minorTermEnglishName.parseEmpty())
        resultValueTxt.text = info.adjustedDisplayResult.parseEmpty()
        resultUnitTxt.text = info.adjustedUnit
        resultUnitTxt.visibility = View.VISIBLE
        val chartLable:String
        if(!info.sampleType.isNullOrEmpty()&&info.sampleType.contains("24")){
            chartLable = getString(R.string.total_txt)
        }else{

            chartLable = getString(R.string.concentration_txt)
        }
        val isShowTwoValue = (getString(R.string.urine_24_txt) == info.sampleType && getString(R.string.urinary_microalbumin_txt) == info.minorTermName) || getString(R.string.whole_process_c_reactive_protein_txt) == info.minorTermName
        if(isShowTwoValue){
            resultValue2Txt.visibility = View.VISIBLE
            resultUnit2Txt.visibility = View.VISIBLE
            resultValue2Txt.text = info.primaryDisplayResult.parseEmpty()
            resultUnit2Txt.text = info.primaryUnit
        }else{
            resultValue2Txt.visibility = View.GONE
            resultUnit2Txt.visibility = View.GONE
        }
        detailMarkerView.setShowSingleValue(!isShowTwoValue)
        chartUnitText.text =info.resPlotLegendLabel.let { if(it.isNullOrEmpty()) String.format("%s(%s)",chartLable,info.adjustedUnit) else it }
        checkerNameTxt.text = String.format("%s%s",getString(R.string.test_fix),info.detectionUserName.parseEmpty())
        productName2Txt.text = info.minorTermAndResultDisplay.parseEmpty()
        ageTxt.text = String.format("%s%s",getString(R.string.age_fix),info.detectionUserAge)
        timeTxt.text = String.format(getString(R.string.cai_time_fix),info.collectDate.parseEmpty())
        sampleTxt.text = String.format(getString(R.string.sample_format_txt),info.sampleType.parseEmpty())
        val dataMap:Map<String,List<HealthRecordDetailsItem>> = info.healthRecordDetails
            .groupBy { it.collectDate.let {date-> if(date.isNullOrEmpty()||date.length<10) date else date.substring(0,10) } }
        val chartList = ArrayList<Pair<String,List<HealthRecordDetailsItem>?>>()
        val calendar = Common.parseFormat(info.collectDate,Common.yymmdd2)?:Calendar.getInstance()
        var dayOneIndex = -1
        val currentMonth = calendar.get(Calendar.MONTH)+1
        (0..35).forEach { count->
            calendar.add(Calendar.DAY_OF_MONTH,if(count==0) 0 else -1)
            val day = calendar.get(Calendar.DAY_OF_MONTH)
            val month = calendar.get(Calendar.MONTH)+1
            if(month == currentMonth&&day==1){
                dayOneIndex = count
            }
            val date = String.format("%d/%s/%s",calendar.get(Calendar.YEAR),month.formatTwo(),day.formatTwo())

            chartList.add(0,Pair(date,dataMap[date]))
        }

        dayOneIndex = if(dayOneIndex==-1) 0 else 35-dayOneIndex

        setChartData(scatterChart,chartList,dayOneIndex)
        nextTimeTxt.text = String.format(getString(R.string.next_cai_time_fix),info.nextCollectDate.parseEmpty())
//        valueTxt1.formatHtml(info.minorTermDescription)
        RichText.fromHtml(info.minorTermDescription?:"").into(valueTxt1)
        if(info.warningMsg.isNullOrEmpty()){
            reportErrorTxt.visibility = View.GONE
        }else{
            reportErrorTxt.text = info.warningMsg
            reportErrorTxt.visibility = View.VISIBLE
        }

        shareView.apply {
            findViewById<TextView>(R.id.titleView).text = String.format("%s%s",info.minorTermName.parseEmpty(),getString(R.string.dete_report))
            findViewById<TextView>(R.id.productNameTxt).text = String.format("%s (%s)",info.minorTermName.parseEmpty(),info.minorTermEnglishName.parseEmpty())
            findViewById<TextView>(R.id.resultValueTxt).text = info.adjustedDisplayResult.parseEmpty()
            findViewById<TextView>(R.id.resultUnitTxt).text = info.adjustedUnit
            val chartLable:String
            if(!info.sampleType.isNullOrEmpty()&&info.sampleType.contains("24")){
                chartLable = getString(R.string.total_txt)
            }else{
                chartLable = getString(R.string.concentration_txt)
            }
            if(isShowTwoValue){
                findViewById<TextView>(R.id.resultValue2Txt).visibility = View.VISIBLE
                findViewById<TextView>(R.id.resultUnit2Txt).visibility = View.VISIBLE
                findViewById<TextView>(R.id.resultValue2Txt).text = info.primaryResult.parseEmpty()
                findViewById<TextView>(R.id.resultUnit2Txt).text = info.primaryUnit
            }else{
                findViewById<TextView>(R.id.resultValue2Txt).visibility = View.GONE
                findViewById<TextView>(R.id.resultUnit2Txt).visibility = View.GONE
            }
            if(info.warningMsg.isNullOrEmpty()){
                findViewById<TextView>(R.id.reportErrorTxt).visibility = View.GONE
            }else{
                findViewById<TextView>(R.id.reportErrorTxt).text = info.warningMsg
                findViewById<TextView>(R.id.reportErrorTxt).visibility = View.VISIBLE
            }
            findViewById<TextView>(R.id.chartUnitText).text = info.resPlotLegendLabel.let { if(it.isNullOrEmpty()) String.format("%s(%s)",chartLable,info.adjustedUnit) else it }
            findViewById<TextView>(R.id.productName2Txt).text = info.minorTermAndResultDisplay.parseEmpty()
            findViewById<TextView>(R.id.timeTxt).text = String.format(getString(R.string.cai_time_fix),info.collectDate.parseEmpty())
            findViewById<TextView>(R.id.sampleTxt).text = String.format(getString(R.string.sample_format_txt),info.sampleType.parseEmpty())
            setChartData(findViewById<BubbleChart>(R.id.scatterChart),chartList,dayOneIndex)
            findViewById<TextView>(R.id.checkerNameTxt).text =
                ComplexSpannableStringUtils.getBuilder(getString(R.string.test_fix))
                    .append(info.detectionUserName.parseEmpty())
                    .setBlur(15f,BlurMaskFilter.Blur.NORMAL)
                    .create()
            findViewById<TextView>(R.id.ageTxt).text =
                ComplexSpannableStringUtils.getBuilder(getString(R.string.age_fix))
                    .append(info.detectionUserAge.parseEmpty())
                    .setBlur(15f,BlurMaskFilter.Blur.NORMAL)
                    .create()
        }
    }
    private lateinit var detailMarkerView: DetailMarkerView

    private fun initChart(chart:BubbleChart,isShare:Boolean){
        chart.setNoDataText(getString(R.string.status_layout_manager_empty))
        chart.setNoDataTextColor(Color.parseColor("#c7c7c7"))
        chart.setDrawGridBackground(false)
        chart.setTouchEnabled(true)
        chart.setScaleEnabled(false)
        if(!isShare){
            detailMarkerView = DetailMarkerView(this).apply {
                chartView = chart
            }
            chart.marker = detailMarkerView
        }
        chart.setMaxVisibleValueCount(200)
        chart.setPinchZoom(false)

        chart.legend.isEnabled = false
        chart.description.isEnabled = false

        val yl = chart.axisLeft
//        yl.spaceTop = 30f
//        yl.spaceBottom = 30f
        yl.setLabelCount(5,true)
        yl.axisMinimum = 0f
        yl.setDrawZeroLine(false)
        yl.textSize = 10f

        yl.textColor = Color.parseColor("#66000000")

        chart.axisRight.isEnabled = false

        val xl = chart.xAxis
        xl.axisMinimum = -1f
        xl.setDrawGridLines(true)
        xl.position = XAxis.XAxisPosition.BOTTOM
        xl.labelRotationAngle = 315f
        xl.setAvoidFirstLastClipping(true)
        xl.textSize = 10f
        xl.textColor = Color.parseColor("#66000000")
        chart.rendererLeftYAxis = YBubbleAxisRenderer(chart.viewPortHandler,chart.axisLeft,chart.getTransformer(AxisDependency.LEFT))
        chart.invalidate()

    }
    private val dotSize = 6f.dp2px.toFloat()
//    private val chartContentRate = 0.86f
    private fun setChartData(chart:BubbleChart,data: List<Pair<String,List<HealthRecordDetailsItem>?>>,dayOneIndex:Int){

        chart.xAxis.setValueFormatter { value, _ ->
            if(value<0||value>=data.size) ""
            else if((value.toInt()-dayOneIndex)%5==0) data[value.toInt()].first.let { if(it.isNullOrEmpty()||it.length<10) it else it.substring(5,10) }
            else ""
        }
        chart.xAxis.labelCount = data.size+1
        chart.xAxis.axisMaximum = data.size.toFloat()

        var min:Float? = null
        var max:Float? = null
        val values: List<BubbleEntry> = data.flatMapIndexed{ index, items ->
            if(!items.second.isNullOrEmpty()){
                items.second!!.map { chartInfo->
                    val value = chartInfo.adjustedResPlot.toFloat()
                    if (min==null||min!! >value) {
                        min = value
                    }
                    if (max==null||max!! < value) {
                        max = value
                    }
                    BubbleEntry(index.toFloat(),value,dotSize,chartInfo)
                }
            }else{
                listOf(BubbleEntry(index.toFloat(),0f,0f))
            }

        }

        chart.axisLeft.let {yl->
            if(min==null){
                yl.axisMinimum = 0f
                yl.axisMaximum = 0f
            }else{
                var minK = min!!*0.98f
                var maxK = max!!*1.02f
                val dbd = (maxK - minK) / (maxK + minK)
                if(dbd<0.5f){
                    val value = maxK + minK
                    minK = value*(1f/4)
                    maxK = value*(3f/4)
                }
                yl.axisMinimum = minK
                yl.axisMaximum = maxK
            }

        }
        val bubbleDataSet = BubbleDataSet(values, "")
        bubbleDataSet.setDrawIcons(false)
        bubbleDataSet.setColor(ContextCompat.getColor(this,R.color.c_831cb5), 255)
        bubbleDataSet.setDrawValues(false)
        bubbleDataSet.isNormalizeSizeEnabled = false
        val dataSets: ArrayList<IBubbleDataSet> = ArrayList()
        dataSets.add(bubbleDataSet)
        val bubble = BubbleData(dataSets)
        bubble.setDrawValues(false)
        bubble.setHighlightCircleWidth(1.5f)
        chart.data = bubble
        chart.invalidate()
    }

    override fun onDestroy() {
        super.onDestroy()
        RichText.recycle()
    }

    override fun setupArguments(args: Bundle?) {
        detectionId = args?.getString(Constants.BUNDLE_ID)?:""
    }
}